package br.ucb.cm.main.common;

import java.util.List;
import java.util.Map;

import br.ucb.cm.board.bean.Location;
import br.ucb.cm.board.bean.Move;
import br.ucb.cm.board.bean.Piece;
import br.ucb.cm.board.ui.BoardController;
import br.ucb.cm.board.ui.BoardGame;
import br.ucb.cm.board.ui.BoardPane;
import br.ucb.cm.board.util.BoardUtil;
import br.ucb.cm.config.bean.PieceConfig;
import br.ucb.cm.main.common.GeneralConstants.PlayerEnum;
import br.ucb.cm.main.mainview.GameController;

public abstract class PlayerController implements BoardController{
	protected BoardPane boardPane;
	protected PlayerEnum player;
	protected boolean canUseBoard;
	protected boolean isThereMovements;
	protected GameController controller;
	protected int points;

	public PlayerController(GameController controller, BoardPane boardPane, PlayerEnum player) {
		super();
		this.controller = controller;
		this.player = player;
		this.boardPane = boardPane;
		this.canUseBoard = false;
	}

	public PlayerEnum getPlayer() {
		return player;
	}

	public void setPlayer(PlayerEnum player) {
		this.player = player;
	}

	public BoardPane getBoardPane() {
		return boardPane;
	}

	public void setBoardPane(BoardPane boardPane) {
		this.boardPane = boardPane;
	}

	public void useAsController(){
		boardPane.setController(this);
		
		if(!isThereMovements()){
			isThereMovements = false;
			doAction(ActionEnum.NO_MOVE, player);
		}
		else
			isThereMovements = true;
	}

	public boolean canUseBoard() {
		return canUseBoard;
	}

	public void setCanUseBoard(boolean canPlay) {
		this.canUseBoard = canPlay;
	}

	@Override
	public Object doAction(ActionEnum action) {
		switch (action) {
		case PLAY:
			return new Boolean(canUseBoard());
		case GET_PLAYER:
			return getPlayer();
		default:
			break;
		}

		return null;
	}

	private PieceConfig checkDeathPiece(Move move) {
		Map<Location, PieceConfig> map = boardPane.getPieceMap();

		if(map.containsKey(move.getDestination()))
			return map.get(move.getDestination());
		return null;
	}

	@Override
	public Object doAction(ActionEnum action, Object object) {
		switch (action) {
		case MOVE:
			Move move = (Move) object;
			PieceConfig deathPiece = checkDeathPiece(move);

			if(deathPiece != null){
				points += deathPiece.getPoints().intValue();
				controller.refreshStatus(points, deathPiece, player);
			}

			((BoardGame) boardPane).applyMove(move);

			controller.finishedTurn();
			break;
		case NO_MOVE:
			controller.callGameToFinish();
			break;
		default:
			break;
		}

		return null;
	}
	
	protected boolean isThereMovements() {
		List<Piece> pieces = BoardUtil.mountPieceList(boardPane.getPieceMap(), player);
		Map<Location, PieceConfig> map = boardPane.getPieceMap();
		
		return !(BoardUtil.getAttacksForPieceList(pieces, player, map).isEmpty() &&
				 BoardUtil.getMovesForPieceList(pieces, player, map).isEmpty());
			
	}


}
